using System.Collections.Generic;
using Kopernikus.Collections.Generic;
using Kopernikus.Parsing.LR;

namespace Kopernikus.Parsing.Earley
{
    public class EarleyGoal
    {
        private readonly List<EarleyItem> m_goalItems = new List<EarleyItem>();
        private readonly List<Production> m_goalProductions = new List<Production>();

        public EarleyGoal(IGrammar grammar, EarleyDFA dfa, int initialState)
        {
            Set<int> goalStates = new Set<int>();
            foreach (Production production in grammar.StartProductions)
            {
                LR0Item goalItem = new LR0Item(production, production.RHS.Length);

                foreach (int goalState in dfa.GetStatesContaining(goalItem))
                {
                    if (goalStates.Contains(goalState))
                    {
                        continue;
                    }
                    goalStates.Add(goalState);
                    m_goalProductions.Add(production);
                    m_goalItems.Add(EarleyItem.Create(goalState, initialState));
                }
            }
        }

        public bool TryGetGoal(Set<EarleyItem> stateSet, out Production goalProduction, out EarleyItem goalItem)
        {
            for (int i = 0; i < m_goalItems.Count; ++i)
            {
                if (stateSet.Contains(m_goalItems[i]))
                {
                    goalItem = m_goalItems[i];
                    goalProduction = m_goalProductions[i];
                    return true;
                }
            }
            goalProduction = default(Production);
            goalItem = default(EarleyItem);
            return false;
        }
    }
}